using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class MatingUI : MonoBehaviour {
	public GUISkin mainSkin;
	
	public float SELECTOFFSPRING_SCALE=2.5f;
	public float SELECTMATE_SCALE=1.5f;	
	
	public AlienStatsUI playerUI;
	public AlienStatsUI featuredStats;
	public List<AlienStatsUI> mates;
	public List<AlienStatsUI> children;
	public AlienStatsUI enemyPreview;

	public delegate void ButtonEvent ();
	public event ButtonEvent done;
	public event ButtonEvent confirmOffspring;
	
	
	// Use this for initialization
	public bool testing= true;
	void Start () {
		
		//TESTING
		//TESTING
		//TESTING
		if(testing) {
			GameObject alien1= AlienMating.spawnAlien(1);
			
			//Put the player alien in the playerUI square
			playerUI.attachAlien( alien1.GetComponent<AlienGenome>());
			//return;
			foreach(AlienStatsUI mate in mates) {
			
				GameObject alien= AlienMating.spawnAlien(1);
			
				//Put the player alien in the playerUI square
				mate.attachAlien( alien.GetComponent<AlienGenome>());		
			}
			state= STATE.PICK_MATE;
		}
		//END TESTING
		//END TESTING
		//END TESTING
	}
	
	public void startMating( AlienGenome playerAlien, int mateDifficulty=1, int modRange=0, AlienGenome enemyAlien=null) {
		GameObject dupAlien= AlienMating.duplicateAlien(playerAlien);			
		playerUI.attachAlien(dupAlien.GetComponent<AlienGenome>());
		
		destroyPreview();
		if(enemyAlien != null) {
			GameObject dupEnemy= AlienMating.duplicateAlien(enemyAlien);			
			enemyPreview.attachAlien(dupEnemy.GetComponent<AlienGenome>());
		}
	
		destroyMates();
		foreach(AlienStatsUI mate in mates) {
			mate.gameObject.transform.localScale= new Vector3(1,1,1);
			
			int modifier= Random.Range(0,modRange+1);
			
			GameObject alien= AlienMating.spawnAlien(mateDifficulty+modifier);
		
			//Put the player alien in the playerUI square
			mate.attachAlien( alien.GetComponent<AlienGenome>());
			mate.rotate= false;
		}
		
		foreach(AlienStatsUI child in children) {
			child.gameObject.transform.localScale= new Vector3(1,1,1);
			child.rotate= false;
		}
		
		state= STATE.PICK_MATE;
	}
	
	// Update is called once per frame	
	private enum STATE {PICK_MATE, CONFIRM_MATE, PICK_OFFSPRING, CONFIRM_OFFSPRING, DONE};
	private STATE state= STATE.PICK_MATE;
	private AlienStatsUI pickedMate;
	private AlienStatsUI pickedOffspring;
	public AlienStatsUI finalOffspring;
	void Update () {
		
		if(state == STATE.PICK_MATE || state == STATE.CONFIRM_MATE) {
		
			AlienStatsUI newMate= null;
			if(testSelectFrom(mates, out newMate)) {
				if(newMate == pickedMate) {
					releaseConfirmMate();
					state= STATE.PICK_MATE;
				}
				else {
					releaseConfirmMate();
					gotoConfirmMate(newMate);
				}
			}
	
		}
		if(state == STATE.PICK_OFFSPRING || state == STATE.CONFIRM_OFFSPRING) {
			
			AlienStatsUI newChild= null;
			if(testSelectFrom(children, out newChild)) {
				if(newChild == pickedOffspring) {
					releaseConfirmOffspring();
					state= STATE.PICK_OFFSPRING;
				}
				else {
					releaseConfirmOffspring();
					gotoConfirmOffspring(newChild);
				}
			}
		}
	}
	
	bool testSelectFrom(List<AlienStatsUI> list, out AlienStatsUI selected) {
		selected= null;
		//Pick
		if(Input.GetMouseButtonDown(0))
		{
			Ray ray= Camera.main.ScreenPointToRay(Input.mousePosition);
			RaycastHit hit= new RaycastHit();
			int layermask = 1 << LayerMask.NameToLayer("Alien");
			if( Physics.Raycast(ray, out hit, layermask) )
			{
				
				//did hit mate
				foreach(AlienStatsUI option in list) {
					if(hit.collider.gameObject == option.target.gameObject) {
//						Debug.Log("Hit!: " + option.gameObject.name);
						selected= option;
						return true;
					}
				}					
			}
		}	
		return false;
	}
	
	void OnGUI() { 
		GUI.skin= mainSkin;
		if(state == STATE.CONFIRM_MATE)
		{					
			Vector3 worldPoint= featuredStats.transform.position;
			Vector2 screenCoord= Camera.mainCamera.WorldToViewportPoint (worldPoint);
				screenCoord.x-= 0.25f/2f;
				screenCoord.y-= 0.33f;
			if(GUI.Button( new Rect(screenCoord.x * (float)Screen.width, (1-screenCoord.y)* (float)Screen.height, Screen.width *0.33f, Screen.height *0.15f), "Confirm Mate")){
				setFeatured(null);
				gotoPickOffspring(pickedMate);				
			}
		}
		if(state == STATE.CONFIRM_OFFSPRING) {
			Vector3 worldPoint= featuredStats.transform.position;
			Vector2 screenCoord= Camera.mainCamera.WorldToViewportPoint (worldPoint);
				screenCoord.x-= 0.28f/2f;
				screenCoord.y-= 0.40f;
			
			if(GUI.Button( new Rect(screenCoord.x * (float)Screen.width, (1-screenCoord.y)* (float)Screen.height, Screen.width *0.40f, Screen.height *0.15f), "Confirm Offspring")){
				//setFeatured(null);
				//gotoPickOffspring(pickedOffspring);
				gotoDone(pickedOffspring);
			}				
		}
		if( state == STATE.DONE ) {
			Vector2 screenCoord= new Vector2(0.6f, 0.15f);
			if(GUI.Button( new Rect(screenCoord.x * (float)Screen.width, (1-screenCoord.y)* (float)Screen.height, Screen.width *0.40f, Screen.height *0.15f), "Fight!")){
				if(done != null)
					done();
			}	
		}
	}
	
	
	
	
	private void gotoConfirmMate( AlienStatsUI mate) {
		
		state= STATE.CONFIRM_MATE;
		pickedMate= mate;		
		mate.gameObject.transform.localScale= new Vector3(SELECTMATE_SCALE, SELECTMATE_SCALE, SELECTMATE_SCALE);
		pickedMate.rotate= true;
		setFeatured(mate);
	}
	
	private void releaseConfirmMate() {
		//Release Previous Pick
		if(pickedMate != null) {
			pickedMate.gameObject.transform.localScale= new Vector3(1f, 1f, 1f);
			pickedMate.rotate= false;
		}
		pickedMate= null;
		setFeatured(pickedMate);
	}
	
	
	private void gotoPickOffspring( AlienStatsUI mate) {
		pickedMate= mate;
		state= STATE.PICK_OFFSPRING;
		
		foreach( AlienStatsUI child  in children) {
			GameObject alien= AlienMating.generateChild(playerUI.target, pickedMate.target);
			
			//Put the player alien in the playerUI square
			child.attachAlien( alien.GetComponent<AlienGenome>());
		}
	}
	
	private void gotoConfirmOffspring( AlienStatsUI offspring) {
		
		state= STATE.CONFIRM_OFFSPRING;
		pickedOffspring= offspring;		
		pickedOffspring.gameObject.transform.localScale= new Vector3(SELECTOFFSPRING_SCALE, SELECTOFFSPRING_SCALE, SELECTOFFSPRING_SCALE);
		pickedOffspring.rotate= true;
	}
	
	private void releaseConfirmOffspring() {
		//Release Previous Pick
		if(pickedOffspring != null) {
			pickedOffspring.gameObject.transform.localScale= new Vector3(1f, 1f, 1f);
			pickedOffspring.rotate= false;
		}
		pickedOffspring= null;
	}
	
	
	private void gotoDone(AlienStatsUI offspring ){

		state= STATE.DONE;
		finalOffspring= offspring;
		
		setFeatured(finalOffspring);
		
		
		foreach( AlienStatsUI child  in children) {
			if(child != finalOffspring)		
				Destroy(child.target.gameObject);
			else
				finalOffspring.target.gameObject.SetActiveRecursively(false);
		}		
		
		if( confirmOffspring != null)
			confirmOffspring();		
	}
	
	
	
	
	private GameObject featuredObj;
	private void setFeatured( AlienStatsUI featured) {
		if(featuredObj != null) {
			Destroy(featuredObj);	
		}
		if(featured != null) {
			AlienGenome genome= featured.target.gameObject.GetComponent<AlienGenome>();
			featuredObj= AlienMating.duplicateAlien(genome);			
			featuredStats.attachAlien(featuredObj.GetComponent<AlienGenome>());
		}
	}
	

	
	public void destroyAll() {
		destroyPlayerAlien();
		destroyPreview();
		destroyMates();
		destroyOffspring();
		setFeatured(null);
	}
	
	public void destroyPlayerAlien() {
		Destroy(playerUI.target.gameObject);
	}
	
	public void destroyPreview(){
		if(enemyPreview.target != null)
		Destroy(enemyPreview.target.gameObject);
	}
	
	public void destroyMates() {
		foreach(AlienStatsUI mate in mates) {
			if(mate.target != null)
				Destroy(mate.target.gameObject);	
		}
	}
	
	public void destroyOffspring() {
		foreach(AlienStatsUI child in children) {
			if(child.target != null)
				Destroy(child.target.gameObject);	
		}
		if(finalOffspring.target != null)
			Destroy(finalOffspring.target.gameObject);
	}
}

